package liangtWorkSpace.rsa;

/**
 * @ClassName RSASignle
 * @Description : 功能说明
 * @Author : LiangT
 * @Date : 2020/4/9 21:57
 */

import org.junit.jupiter.api.Test;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;

/**
 * RSA验签与签名
 */
public class RSASignle {
    private static final String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALpwy/kkI5itvZCqyPTXTfB+koBfgxV6XccNcjt/1l5v7HKe6vE+DL1ghAfYBiHg3/8mVdU/Id96qbWUMOd60NoEE2zJQBFFC5XZ05X3UixW94LPujyvjfRlR9SoMIZZF+lechrk8qMFKBmmjBTYzmLzzBXPOF403cYaaZ9ntBENAgMBAAECgYBPz6+RtMXEO0P2JRYnse98b0KZz8lWrW5torTvAZesD6+hlaQvp4denm2GyhQ99n0NRcTip8cBWwpBX/HbdfjnTzpOjl0sIGJLG2Nr1TLnYLKGFDuhRZ6aUJywKANkJq+cVpcRCmLW+auvJ/ywskHvpZwcb8tkJ6sO12w91Oq4IQJBAPQa44Or7XU9pr06gRcLgtSg21oXvBdsZapTcsGq59VC6kcYiJVV1otGGUHSXmNYrcVubnv+ct0eRKOHJgbSotUCQQDDhpFZsUfLnxKxVrRrfQhIydcYCKtqUOFKbQjOrsC97GuAsYxigJAZ0+e0UtmpzcOjn5ldZJswVeXxmuoBjCFZAkEAxalwSZLSeXkup1PUbCC6FAsdE9rcR+tSd5WS+xe1Go9Qvbk0ABi93ZEpqo76N1/7dj9x352uzTZRRkmNlUDC8QJANu/iex8SmyXQ7L795o20/C6qHvigoTikdHL6XIhBY5vAAOLiHPMeigM+QS5eNhW4eIrpXpJcAFLCTwZF5bVn0QJAd3AQYzUNd2SF2NXgWt2LQo54iw6bvxbiVs49VGpnqkps+1E9g9+yDlF95zTj/sf8HVSN/HUX4cBuSoHqij5aNw==";
    private static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6cMv5JCOYrb2Qqsj0103wfpKAX4MVel3HDXI7f9Zeb+xynurxPgy9YIQH2AYh4N//JlXVPyHfeqm1lDDnetDaBBNsyUARRQuV2dOV91IsVveCz7o8r430ZUfUqDCGWRfpXnIa5PKjBSgZpowU2M5i88wVzzheNN3GGmmfZ7QRDQIDAQAB";

    /**
     * 私钥生成签名
     * @param data
     * @return
     */
    public static String sign(byte[] data,String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        // 解密由base64编码的私钥
        byte[] keyBytes = Base64Util.decoder(privateKey);
        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(RSAConfig.getKeyAlgorithm());

        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance(RSAConfig.getSignatureAlgorithm());
        signature.initSign(priKey);
        signature.update(data);

        return Base64Util.encoder(signature.sign());
    }

    /**
     * 校验数字签名
     *
     * @param data      加密数据
     * @param publicKey 公钥
     * @param sign      数字签名
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     */
    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {

        // 解密由base64编码的公钥
        byte[] keyBytes = Base64Util.decoder(publicKey);

        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(RSAConfig.getKeyAlgorithm());

        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(RSAConfig.getSignatureAlgorithm());
        signature.initVerify(pubKey);
        signature.update(data);

        // 验证签名是否正常
        return signature.verify(Base64Util.decoder(sign));
    }


    @Test
    public void single() throws Exception {
        String str = "要签名的串";
        String single = RSASignle.sign(str.getBytes(),privateKey);
        System.out.println("生成的签名串："+single);
        String sign = "KJp2hwbRI+BMjaylZfWtdTb5Ru2n9UsvNAcIod+QN/hqZePauDCnqivnpSGFxhv6ZTPhdLV286V5ZG/Ro/AoKVeTyRc6nKVTlC4N6EYUb+r73ru0U9Q6qHJWDMGkTl5k/zkByNXJMWnzKEB60n3TxZD8i57eAO9tP3G1h4nvkdA=";
        String rsaCode="UmVnaXN0ZXJSZXF1ZXN0KGxvZ2luTm89NjIxMjg3MjExMDYyMjk5MywgcHN3ZD1udWxsLCByZWdDaGFubmVsPTcsIGNoZWNrQ29kZT1udWxsLCBzaW5nbGVEYXRhPW51bGwsIHNpbmdsZURhdGVUaW1lPW51bGwsIGFjY3RObz1udWxsLCB2ZXJpZnlUeXBlPTIp";
        System.out.println("验签结果："+ RSASignle.verify(rsaCode.getBytes(),publicKey,sign));
    }

    public static void main(String[] args) throws Exception {
//        私钥：MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALpwy/kkI5itvZCqyPTXTfB+koBfgxV6XccNcjt/1l5v7HKe6vE+DL1ghAfYBiHg3/8mVdU/Id96qbWUMOd60NoEE2zJQBFFC5XZ05X3UixW94LPujyvjfRlR9SoMIZZF+lechrk8qMFKBmmjBTYzmLzzBXPOF403cYaaZ9ntBENAgMBAAECgYBPz6+RtMXEO0P2JRYnse98b0KZz8lWrW5torTvAZesD6+hlaQvp4denm2GyhQ99n0NRcTip8cBWwpBX/HbdfjnTzpOjl0sIGJLG2Nr1TLnYLKGFDuhRZ6aUJywKANkJq+cVpcRCmLW+auvJ/ywskHvpZwcb8tkJ6sO12w91Oq4IQJBAPQa44Or7XU9pr06gRcLgtSg21oXvBdsZapTcsGq59VC6kcYiJVV1otGGUHSXmNYrcVubnv+ct0eRKOHJgbSotUCQQDDhpFZsUfLnxKxVrRrfQhIydcYCKtqUOFKbQjOrsC97GuAsYxigJAZ0+e0UtmpzcOjn5ldZJswVeXxmuoBjCFZAkEAxalwSZLSeXkup1PUbCC6FAsdE9rcR+tSd5WS+xe1Go9Qvbk0ABi93ZEpqo76N1/7dj9x352uzTZRRkmNlUDC8QJANu/iex8SmyXQ7L795o20/C6qHvigoTikdHL6XIhBY5vAAOLiHPMeigM+QS5eNhW4eIrpXpJcAFLCTwZF5bVn0QJAd3AQYzUNd2SF2NXgWt2LQo54iw6bvxbiVs49VGpnqkps+1E9g9+yDlF95zTj/sf8HVSN/HUX4cBuSoHqij5aNw==
//        公钥：MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6cMv5JCOYrb2Qqsj0103wfpKAX4MVel3HDXI7f9Zeb+xynurxPgy9YIQH2AYh4N//JlXVPyHfeqm1lDDnetDaBBNsyUARRQuV2dOV91IsVveCz7o8r430ZUfUqDCGWRfpXnIa5PKjBSgZpowU2M5i88wVzzheNN3GGmmfZ7QRDQIDAQAB
        String str = "要签名的串";
        Map map = RSAGetKey.getKey();
        String privateKey = String.valueOf(map.get(RSAConfig.getPrivateKey()));
        String publicKey = String.valueOf(map.get(RSAConfig.getPublicKey()));
        System.out.println("私钥："+privateKey);
        System.out.println("公钥："+publicKey);
        String single = RSASignle.sign(str.getBytes(),privateKey);
        System.out.println("生成的签名串："+single);
        System.out.println("验签结果："+ RSASignle.verify(str.getBytes(),publicKey,single));
    }
}
